package com.cseg674.dataquery;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; 

import com.hp.hpl.jena.query.*;  
import com.cseg674.datamanagement.adler.*; 
/**
 * Servlet implementation class SparqlQueryServlet
 */
public class SparqlQueryServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private static Adler adler;
	private static final String ontologyURL = 
		"http://cseg674.googlecode.com/svn/trunk/CSEG674/ontology/source.owl#";
    
    public SparqlQueryServlet() {
        super();
    }
  
	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doPost(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		response.setContentType("text/html"); 
		 
		String query = request.getParameter("QueryArea");
		String prjName = request.getParameter("PrjName"); 
		String type = request.getParameter("type"); 
		 
		if(type != null){
			String results = "";
			if(type.equals("Class")){
				results = getAllClasses(prjName);
			}
			else if(type.equals("Method")){
				results = getAllMethods(prjName);
			}
			else if(type.equals("MemberVariable")){
				results = getAllMemberVariables(prjName);
			}
			else if(type.equals("MVType")){
				results = getAllMVTypes(prjName);
			}
			else if(type.equals("ReturnType")){
				results = getAllReturnTypes(prjName);
			}
			response.setContentType("text/xml");
			response.getWriter().write(results);
		}
		else{
			ResultSet results = queryRDFData(prjName, query);  
			request.setAttribute("Results", results);  
			RequestDispatcher rd = request.getRequestDispatcher("sparql-result.jsp");
			rd.forward(request, response); 
		}
	}
	
	private ResultSet queryRDFData(String prjName, String queryString){
		
		ResultSet results = null;
		
		try{
			Adler adler = getAdler();
			results = adler.submitQuery(prjName, queryString);
		}
		catch(AdlerException aex){
			System.out.println("AdlerException: "+aex.getMessage());
		}
		catch(Exception ex){
			ex.printStackTrace();
		}
		return results;
	}
	
	private String getAllClasses(String prjName){
		 
		String queryString = 
			"PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> "+
			"PREFIX j.0: <"+ontologyURL+"> "+
			"SELECT DISTINCT ?Class_0 "+
			"WHERE {"+
			"       ?thing0 rdf:type j.0:Class . "+
			"	    ?thing0 j.0:named ?Class_0 . "+
			"}";
		return executeQuery(prjName, queryString);
	}
	
	private String getAllMethods(String prjName){
		 
		String queryString = 
			"PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> "+
			"PREFIX j.0: <"+ontologyURL+"> "+
			"SELECT DISTINCT ?Method_0 "+
			"WHERE {"+
			"       ?thing0 rdf:type j.0:Method . "+
			"	    ?thing0 j.0:named ?Method_0 . "+
			"}";
		return executeQuery(prjName, queryString);
	}
	
	private String getAllMemberVariables(String prjName){
		 
		String queryString = 
			"PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> "+
			"PREFIX j.0: <"+ontologyURL+"> "+
			"SELECT DISTINCT ?MemberVariable_0 "+
			"WHERE {"+
			"       ?thing0 rdf:type j.0:MemberVariable . "+
			"	    ?thing0 j.0:named ?MemberVariable_0 . "+
			"}";
		return executeQuery(prjName, queryString);
	}
	
	private String getAllMVTypes(String prjName){
		 
		String queryString = 
			"PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> "+
			"PREFIX j.0: <"+ontologyURL+"> "+
			"SELECT DISTINCT ?MVType_0 "+
			"WHERE {"+
			"       ?thing0 rdf:type j.0:MemberVariable . "+
			"	    ?thing0 j.0:named ?MemberVariable_0 . "+
			"       ?thing0 j.0:hasType ?MVType_0 . "+
			"}";
		return executeQuery(prjName, queryString);
	}
	
	private String getAllReturnTypes(String prjName){
		 
		String queryString = 
			"PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> "+
			"PREFIX j.0: <"+ontologyURL+"> "+
			"SELECT DISTINCT ?ReturnType_0 "+
			"WHERE {"+
			"       ?thing0 rdf:type j.0:Method . "+
			"	    ?thing0 j.0:named ?Method_0 . "+
			"       ?thing0 j.0:hasType ?ReturnType_0 . "+
			"}";
		return executeQuery(prjName, queryString);
	}
	
	private Adler getAdler() throws AdlerException{
		if(adler == null){
			adler  = (Adler)getServletContext().getAttribute("adler"); 
			if(adler == null){ 
				adler = new Adler();
				getServletContext().setAttribute("adler", adler);
			}
		}
		return adler;
	}
	
	private String executeQuery(String prjName, String queryString){
		String result = "";
		try{
			adler = getAdler();
			ResultSet rs = adler.submitQuery(prjName, queryString);
			result = ResultSetFormatter.asXMLString(rs);
		}
		catch(AdlerException aex){
			System.out.println("AdlerException: "+aex.getMessage());
		}
		catch(Exception ex){
			ex.printStackTrace();
		}
		return result; 
	}
}
